//
//  RootViewController.m
//  CoreDataDemo
//
//  Created by LZXuan on 15-6-23.
//  Copyright (c) 2015年 轩哥. All rights reserved.
//

#import "RootViewController.h"
#import <CoreData/CoreData.h>
#import "UserModel.h"


/*
 1.#import <CoreData/CoreData.h>
 2.创建CoreData的数据模型文件(类似于数据库的创建表)
 2.这样托管对象模型知道所有当前工程中用到的托管对象的定义
 创建一个NSManagedObjectModel 数据模型文件
 
 //1.创建数据模型文件-》new file->core Data--》选中Data Model，创建文件 （User.xcdatamodeld）在里面创建 数据模型实例Entity(UserModel)
 //2.创建跟数据模型文件关联的数据模型类new file->core Data->选中 NSManagedObject of subclass --》关联上User.xcdatamodeld数据模型文件中的UserModel 实例
 //3.用代码初始化CoreData
 //3.1 导入 #import <CoreData/CoreData.h>
 //3.2 从沙盒包内 读取数据模型文件

 有两种方式:
 a.//获取到coreData文件的路径，并转换成url
 //在包内User.xcdatamodeld会转化为 User.momd
 
 NSString *coreDataPath  =[[NSBundle mainBundle] pathForResource:@"User" ofType:@"momd"];
 //加载coreData文件中的数据,转成model
 NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:[NSURL fileURLWithPath:coreDataPath]];
 
 b.NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
 中的nil表示连接项目中所有的 .xcdatamodeld 文件为一个datamodel，这是一个非常好的方法，把多个entity放在各自的xcodemodel文件中分开管理，然后用这个函数连接起来生成一个datamodel，这样就可以对应一个persistentStore。
//NSLog(@"data:%@",[[NSBundle mainBundle] pathForResource:@"User" ofType:@"momd"]);

//3.2获取 数据模型文件



3.创建协调器
NSPersistentStoreCoordinator

4.//将coreData数据映射到数据库
addPersistentStoreWithType

5.//创建上下文托管对象
NSManagedObjectContext

6增删改查
增加:

 */

@interface RootViewController () <UITableViewDataSource,UITableViewDelegate>
{
    //CoreData 上下文管理对象(进行数据库的增删改查)
    NSManagedObjectContext *_context;
    
    //数据源数组
    NSMutableArray *_dataArr;
}

@property (nonatomic,strong) NSMutableArray *dataArr;
@property (weak, nonatomic) IBOutlet UITextField *nameText;
@property (weak, nonatomic) IBOutlet UITextField *ageText;

- (IBAction)addClick:(UIButton *)sender;
- (IBAction)deleteClick:(UIButton *)sender;
- (IBAction)updateClick:(UIButton *)sender;
- (IBAction)fetchNameClick:(UIButton *)sender;
- (IBAction)fetchAllClick:(UIButton *)sender;
@property (weak, nonatomic) IBOutlet UITableView *tableView;

@end

@implementation RootViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //初始化一个数组
    self.dataArr = [[NSMutableArray alloc] init];
    //设置代理
    self.tableView.dataSource = self;
    self.tableView.delegate = self;
    
    //注册cell  注册的是 UITableViewCellStyleDefault风格的cell
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
    [self coreDataInit];
}
//设置多少分区
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}
//多少行
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.dataArr.count;
}
//获取cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    
    //从数据源获取Model
    UserModel *model = self.dataArr[indexPath.row];
    
    cell.textLabel.text = [NSString stringWithFormat:@"name:%@ age:%@",model.name,model.age.stringValue];
    
    return cell;
    
}


#pragma mark - CoreData初始化
- (void)coreDataInit {
    //NSLog(@"%@",NSHomeDirectory());
    //1.获取 .xcdatamodeld 读成一个 数据模型文件对象
#if 0
    //获取 bundle中的所有 的  .xcdatamodeld 连接成一个对象
    NSManagedObjectModel *fileModel = [NSManagedObjectModel mergedModelFromBundles:nil];
#else
    //[NSURL fileURLWithPath:path] 把本地文件路径转化为NSURL
    //[NSURL URLWithString:xxx]  把一个网址字符串转化为NSURL
    //.xcdatamodeld编译之后 拷贝到app包内 就变成了 .momd文件
    NSString *path = [[NSBundle mainBundle] pathForResource:@"User" ofType:@"momd"];
    NSManagedObjectModel *fileModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path]];
    /*
     .xcdatamodeld内部 类似于 数据库的表
     */
#endif
    //2.设置存储协调器
    //用 数据模型文件 进行初始化 这样 协调器就知道 数据库存的字段有哪些
    NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:fileModel];
    //2.2设置存储类型 (xml、二进制、sqlite)
    //2.3 设置一个数据库存储的地址
    NSString *dataPath = [NSHomeDirectory() stringByAppendingString:@"/Documents/myData.sqlite"];
    
    NSError *error = nil;
    NSPersistentStore *store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:dataPath] options:nil error:&error];
    if (!store) {
        //失败会返回nil
        NSLog(@"addPersistentStore error:%@",error.description);
    }
    //3.创建上下文管理对象 (对数据库进行增删改查)
    _context = [[NSManagedObjectContext alloc] init];
    //设置协调器
    _context.persistentStoreCoordinator = coordinator;
    
}

//增加数据
- (IBAction)addClick:(UIButton *)sender {
    //使用CoreData 的数据模型对象 不能像以前那样创建数据模型对象
    //UserModel *model = [[UserModel alloc] init];
    
    //我们需要创建一个NSEntityDescription
    //内部采用的运行时操作模型对象
    
    //增加一个实体/数据模型对象
    //通过_context上下文 去向数据库增加一个UserModel实例对象
    UserModel *insertModel = (UserModel *)[NSEntityDescription insertNewObjectForEntityForName:@"UserModel" inManagedObjectContext:_context];
    insertModel.name = self.nameText.text;
    insertModel.fName = [self.nameText.text substringToIndex:1];
    insertModel.age = @(self.ageText.text.integerValue);
    //@(100);==>[NSNumber numberWithInteger:100];
    
    //上面 是在 程序的内存中增加一个数据模型对象
    //把数据保存本地
    NSError *error = nil;
    
    //保存数据 --->(用代码增删改之后 一定要注意保存 保存之后才会写入磁盘)
    BOOL ret = [_context save:&error];
    if (!ret) {
        //返回NO 表示保存失败
        NSLog(@"insert Data Error:%@",error.description);
    }
    
}

- (IBAction)deleteClick:(UIButton *)sender {
    //先找到 再删除
    NSArray *arr = [self fetchDataWithName:self.nameText.text];
    //arr指向的数组对象中存放的都是查询的结果数据模型对象地址
    for (UserModel *model in arr) {
        [_context deleteObject:model];//删除指定的模型对象
        //只是从内存上删除
    }
    NSError *error = nil;
    //保存 到本地 和本地磁盘同步
    if (![_context save:&error ]) {
        NSLog(@"delete error:%@",error.description);
    }
    
}

- (IBAction)updateClick:(UIButton *)sender {
    //先找到 再修改
    NSArray *arr = [self fetchDataWithName:self.nameText.text];
    //arr指向的数组对象中存放的都是查询的结果数据模型对象地址
    for (UserModel *model in arr) {
       //修改找到的对象
        //修改年龄
        model.age = @(self.ageText.text.integerValue);
    }
    NSError *error = nil;
    //保存 到本地 和本地磁盘同步
    if (![_context save:&error ]) {
        NSLog(@"update error:%@",error.description);
    }
}

- (IBAction)fetchNameClick:(UIButton *)sender {
    //根据 textField的name 值 查询
    NSArray * arr = [self fetchDataWithName:self.nameText.text];
    //先删除旧数据
    [self.dataArr removeAllObjects];
    //增加新数据
    [self.dataArr addObjectsFromArray:arr];
    //刷新表格
    [self.tableView reloadData];

}

//封装一个函数 按照名字查找
- (NSArray *)fetchDataWithName:(NSString *)newName {
    //1.实例化一个查询请求
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    //2.设置 查询的数据模型
    request.entity = [NSEntityDescription entityForName:@"UserModel" inManagedObjectContext:_context];
    if (newName) {
        //按照名字查询 必须要设置一个谓词
        //表示 谓词 去 过滤表中 所有UserModel 对象name 属性的值
        //匹配 UserModel 对象的name属性的值 是否 完全匹配 newName传入的值
        //假设 newName 是@"xiaohong"
        //@"name like xiaohong"-->数据库的指定的表中 属性name 中有没有叫xiaohong的
        request.predicate = [NSPredicate predicateWithFormat:@"name like %@",newName];
        /*
        NSString *str = [NSString stringWithFormat:@"*%@*",newName];
        request.predicate = [NSPredicate predicateWithFormat:@"name like %@",str];
         @"name like *xiaohong*"-->模糊查询  有没有包含xiaohong字符串的
         */
    }
    //谓词的作用就是来过滤数据 设置搜索条件的
    
    //如果没有设置谓词 默认表示查询表中的所有的数据
    //根据查询 请求 返回 查询结果 返回一个数组
    
    //设置排序准则
    // 按照 model 中的age 属性 升序排列   NO表示 降序
    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:NO];
    request.sortDescriptors = @[sort];

    return [_context executeFetchRequest:request error:nil];
    
}

- (IBAction)fetchAllClick:(UIButton *)sender {
    //查询所有
    NSArray * arr = [self fetchDataWithName:nil];
    //先删除旧数据
    [self.dataArr removeAllObjects];
    //增加新数据
    [self.dataArr addObjectsFromArray:arr];
    //刷新表格
    [self.tableView reloadData];
}
@end





